//Promise 异常处理

function ajax (url) {
    return new Promise(function (resolve, reject) {
        // foo()        执行onRejected
        // throw new Error()      执行onRejected
        //AJAX请求
        var xhr = new XMLHttpRequest()
        //请求方式和地址
        xhr.open('GET', url)
        //请求类型
        //获取结果为json对象而不是字符串
        xhr.responseType = 'json'
        //请求完成过后执行
        xhr.onload = function () {
            if (this.status === 200) {
                //请求成功 返回请求的结果
                resolve(this.response)
            } else {
                //请求失败 返回错误信息 即当前状态文本
                //为promise当中的异常做一些处理
                reject(new Error(this.statusText))
            }
        }
        //开始执行异步请求
        xhr.send()
    }) 
}

//文件路径不存在则会执行请求失败的回调函数
//若promise执行异常 或手动抛出一个异常 onRejected的回调也会被执行
// ajax('/api/users.json')
//     .then(function onFulfilled (value) {
//         console.log('onFulfilled', value);
//         return ajax('/error-url')   //不存在一定失败 但并没有被捕获到
//     }, function onRejected (error) {
//         //promise失败或是异常都会被执行   
//         console.log('onRejected', error);
//     })

//可以用catch方法来注册promise失败/异常时的回调
ajax('/api/users.json')
    .then(function onFulfilled (value) {
        console.log('onFulfilled', value);
        return ajax('/error-url')   //该异常被捕获到
    }) // => promise {} 
    // catch更为常用 利于链式调用 
    //是给上一个then返回的promise做回调 而不是第一个promise
    //能够捕获到后续then操作中的promise的异常  而上方的例子无法捕获其他then返回的promise异常
    .catch(function onRejected (error) {
        //promise失败或是异常都会被执行 
        console.log('onRejected', error);
    }) 


// //不推荐使用      最好是在代码中明确捕获每一个可能的异常
// //可以在全局上注册一个unhandledrejection事件 处理代码中没有被手动捕获的promise异常
// window.addEventListener('unhandledrejection', event => {
//     const { reason, promise } = event
//     console.log(reason, promise);

//     //reason => Promise 失败原因， 一般是一个错误对象
//     // promsie => 出现异常的Promise对象

//     event.preventDefault()
// },false)


// //node当中 process当中注册以下事件
// process.on('unhandledRejection', (reason, promise) => {
//     console.log(reason, promise);
//     //reason => Promise 失败原因， 一般是一个错误对象
//     // promsie => 出现异常的Promise对象
// })